package com.itheima.thread.security.demo04;

public class SellTicket implements Runnable {

    // 记录要出售的总票数
    private static int tickets = 100;
    private Object obj = new Object() ;             // 定义了一把锁

    private int count = 0 ;

    @Override
    public void run() {

        while(true) {                                                // 票没有了，也可能有人来问，所以这里用死循环让卖票的动作一直执行

            if(count % 2 == 0) {

                // SellTicket.class : 当前这个类所对应的字节码文件对象
                // 获取到字节码文件对象有什么用？到反射的时候在来讲
                synchronized (SellTicket.class) {                    // 这个对象可以是任意一个对象，但是有一个前提，多线程在进行访问的时候需要去使用同一个对象

                    // 判断票数大于0，就卖票，并告知是哪个窗口卖的
                    if(tickets > 0) {

                        // 模拟网络延迟
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");

                        // 卖了票之后，总票数要减1
                        tickets-- ;
                    }

                }

            }else {

                sellTicket();

            }

            // 对象count进行++的操作
            count++ ;

        }

    }

    // 就是静态同步方法： 静态同步方法的锁对象不是this，那么到底是谁呢？ 当前这个类所对应的字节码文件对象
    public static synchronized void sellTicket() {

        // 判断票数大于0，就卖票，并告知是哪个窗口卖的
        if(tickets > 0) {

            // 模拟网络延迟
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");

            // 卖了票之后，总票数要减1
            tickets-- ;
        }

    }

    // 同步方法
    /**
     * 会存在问题，存在问题的原因是因为同步方法的锁对象和同步代码块的锁对象是不一样的。同步方法的锁对象到底是谁？
     * 研究的思路：我现在把这个同步代码块的锁对象发生一个改变，然后我们再次运行我们的程序，如果程序没有出现问题，那么就说明我们同步方法的锁对象和你更改完毕以后
     * 同步代码块的锁对象时一致的。
     * 同步方法的锁对象就是this
     */
//    public synchronized void sellTicket() {
//
//        // 判断票数大于0，就卖票，并告知是哪个窗口卖的
//        if(tickets > 0) {
//
//            // 模拟网络延迟
//            try {
//                Thread.sleep(100);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//
//            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
//
//            // 卖了票之后，总票数要减1
//            tickets-- ;
//        }
//
//    }



}
